const glob = require('glob')
const path = require('path')
const fs = require('fs')
const geoip = require('geoip-lite')
const IP2Region = require('ip2region').default
const createCsvWriter = require('csv-writer').createObjectCsvWriter

glob(path.join(__dirname, '../serverlog/*.log'), (err, files) => {
  if (err) return
  const promises = files.map(file => {
    return new Promise((resolve, reject) => {
      fs.readFile(file, 'utf8', (err, data) => {
        if (err) {
          reject(err)
          return
        }
        resolve(data)
      })
    })
  })
  const list = []
  Promise.all(promises).then(results => {
    results.forEach(data => {
      const lines = data.split('\n')
      for (const line of lines) {
        const match = line.match(/\[(.*?)\].*?"ip":"(.*?)".*?"path":"(.*?)".*?"method":"(.*?)"/)
        if (match) {
          const date = match[1]
          const ip = match[2]
          const path = match[3]
          const method = match[4]
          list.push({
            date: date.replace(/\..*/, '').replace(/T/, ' '),
            ip,
            path,
            method
          })
        }
      }
    })
    const ips = [...new Set(list.map(o => o.ip))]
    const geoMap = new Map()
    ips.forEach(ip => {
      geoMap.set(ip, analyzeIp(ip))
    })
    const l = list.map(o => {
      return {
        ...o,
        ...geoMap.get(o.ip)
      }
    }).filter(o => o.country === '中国')
    const csvWriter = createCsvWriter({
      path: './file.csv',
      header: Object.keys(l[0]).map(o => {
        return {
          id: o,
          title: o
        }
      })
    })
    csvWriter.writeRecords(l)
      .then(() => console.log('CSV file has been written successfully'))
      .catch((error) => console.error(error))
  })
})

function analyzeIp (ip) {
  const geo = geoip.lookup(ip)
  const query = new IP2Region()
  const ipAddress = query.search(ip)
  const { country, province, city, isp } = ipAddress || {}
  const { ll, country: countryEn, region: provinceEn, city: cityEn } = geo || {}
  return {
    country,
    province,
    city,
    countryEn,
    provinceEn,
    cityEn,
    isp,
    lonlat: ll?.join(',')
  }
}
